<template>
  <section
    class="photo-gallery-root"
    ref="galleryRootRef"
  >
    <a-grid
      v-if="images.length"
      class="photo-gallery-root_grid"
      :cols="cols"
      :colGap="2"
      :rowGap="2"
    >
      <a-grid-item
        class="grid-item"
        v-for="(item, index) in cloneList"
        :key="index"
        :span="span"
        @click="handleClickPreview(index)"
      >
        <a-image
          :src="item.src"
          :width="imageStyle.width"
          :height="imageStyle.height"
          :preview="false"
          fit="cover"
          @error="handleError(index)"
        >
          <template
            #error
            v-if="item.standby"
          >
            <a-image
              :src="item.standby"
              :preview="false"
              :width="imageStyle.width"
              :height="imageStyle.height"
              fit="cover"
            />
          </template>
        </a-image>

        <div
          v-if="!viewAll && images.length > maxImage && index === maxImage - 1 && !arrange"
          class="photo-gallery-mask"
          @click.stop="handleViewAll"
        >
          <icon-plus />{{ images.length - maxImage }}
        </div>
      </a-grid-item>
    </a-grid>

    <a-image-preview-group
      v-if="preview"
      v-model:visible="previewVisible"
      v-model:current="currentIndex"
      :src-list="previewList"
      infinite
    />
  </section>
</template>

<script setup lang="ts">
  import { IPhotoGalleryProp, IImageItem } from "@/components/photo-gallery/src/types";
  import { onBeforeUnmount, onMounted, ref } from "vue";

  defineOptions({
    name: "PhotoGallery",
  });

  const props = withDefaults(defineProps<IPhotoGalleryProp>(), {
    images: () => [],
    maxImage: 9,
    cols: 3,
    preview: true,
    arrange: false,
  });

  const galleryRootRef = ref<HTMLElement>();
  const cloneList = ref<IImageItem[]>([]);
  const span = ref<number>(1);
  const width = ref<number>(0);
  const imageStyle = ref({
    width: "100%",
    height: 0,
  });
  const viewAll = ref<boolean>(false);
  const previewVisible = ref<boolean>(false);
  const currentIndex = ref<number>(0);
  const previewList = ref<string[]>([]);

  onMounted(() => {
    resize();
    init();
    window.addEventListener("resize", resize);
  });

  onBeforeUnmount(() => {
    window.removeEventListener("resize", resize);
  });

  const resize = () => {
    width.value = galleryRootRef.value?.clientWidth || 0;
  };

  const init = () => {
    if (props.images.length > props.maxImage && !props.arrange) {
      cloneList.value = props.images.slice(0, props.maxImage);
    } else {
      cloneList.value = props.images.map((item) => item);
    }
    // 图片预览列表
    previewList.value = props.images.map((item) => item.src || "");

    // 设置图片参数
    span.value = props.images.length === 1 ? (props.arrange ? 1 : 2) : 1;
    imageStyle.value.width = props.images.length === 1 ? (props.arrange ? "100%" : "") : "100%";
    const singleSpanWidth = width.value / props.cols; // 单格宽度
    imageStyle.value.height = props.images.length === 1 ? (props.arrange ? singleSpanWidth : singleSpanWidth * 2) : singleSpanWidth;
  };

  const handleViewAll = () => {
    viewAll.value = true;
    cloneList.value = props.images.map((item) => item);
  };

  const handleError = (ind: number) => {
    const originImageNode = props.images.find((item, index) => index === ind);
    previewList.value[ind] = originImageNode?.standby || "";
  };

  const handleClickPreview = (ind: number) => {
    currentIndex.value = ind;
    previewVisible.value = true;
  };
</script>
